package siedler.communication;

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;

public class BootstrappingServer extends UnicastRemoteObject implements BootstrappingServerI{
	
	private static final int PORT = 1099;
	private static final String SERVICE = "bootstrapping";
	
	private Vector<PeerI> peerRefs = new Vector<PeerI>();
	private HashMap<Integer,String> peerIdAddressMap = new HashMap<Integer,String>();
	private int currentPeerId = 0;
	
	private int gameId = 0;
	private Vector<Game> games = new Vector<Game>();
	
	private int numberOfPlayers = 3;

	protected BootstrappingServer() throws RemoteException {
		System.out.println("Initializing Server \n");		
	}

	public static void main(String[] args) {
		
		Registry registry = null;
		try {
			registry = LocateRegistry.createRegistry(PORT);
		} catch (RemoteException e) {
			try { registry = LocateRegistry.getRegistry();
			} catch (RemoteException e2) {
				System.out.println("Registry could not be established " + e);
				System.exit(0);
			} //try e2
		} //try e
		System.out.println("Registry established \n");
		
		try {
			BootstrappingServer server = new BootstrappingServer();
			registry.rebind(SERVICE, server);
			registry.rebind(SERVICE, server);
			System.out.println("Registered with registry \n");		
		} catch (RemoteException e){
			System.out.println("Error: " + e);
		} // try register
	} //main
	
	public void registerPeer(PeerI peerRef, String address) throws RemoteException{
		System.out.println("registering peer...");
		peerRefs.add(peerRef);
		peerIdAddressMap.put(currentPeerId, address);
		System.out.println("currentPeerId = " + currentPeerId);
		currentPeerId++;
		
		//add(address);
		
		//if 2 or more peers have connected, start new game
		if(peerRefs.size() > numberOfPlayers - 1){
			
			Game game = new Game(gameId, peerRefs, peerIdAddressMap);
			games.add(game);
			gameId ++;
			
			ServicesI services = new Services("MD5");
			
			peerRefs.clear();
			peerIdAddressMap.clear();
			currentPeerId = 0;
			
			sendGame(game, services);
		}
		//tell peers to wait for other players
		else {
			peerRef.waitForPlayers();
		}		
	}
	
	public void sendGame(Game game, ServicesI services) throws RemoteException{
		PeerI player;
		for(int i = 0; i < game.getPlayers().size(); i++){
			player = game.getPlayers().elementAt(i);
			player.registerServices(services);
			
			player.setId(i);
			player.startReceiveThread();
			player.setPlayers(game.getPlayers());
			player.setIdAddressMap(game.getPlayerIdAddressMap());
			//
			//player.setTokenHolder(player);
			//
			
		}
		for(int i = 0; i < game.getPlayers().size(); i++){
			player = game.getPlayers().elementAt(i);
			try {
				player.startGame(game);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
